package cn.kent.high.juc.lock.lockSupport;

import jdk.nashorn.internal.ir.CallNode;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;

/**
 * 一个先进先出的锁
 * 这个代码在LockSupport的类注释中
 */
public class FIFOMutex {
    private final AtomicBoolean locked = new AtomicBoolean(false);
    private final Queue<Thread> waiters = new ConcurrentLinkedQueue<>();

    public void lock() {
        boolean wasInterrupted = false;
        Thread thread = Thread.currentThread();
        waiters.add(thread);

        // 只有队首的线程可以获取锁 -> 如果当前线程不在队首 或 当前锁已经被其他线程获取
        while (waiters.peek() != thread || locked.compareAndSet(false, true)) {
            LockSupport.park(this); // 挂起自己
            if (Thread.interrupted()) wasInterrupted = true;
        }

        waiters.remove();
        if (wasInterrupted) // 判断标记，如果标记为true，则中断线程
            thread.interrupt(); // 这个标记我用不着，不代表别的项目用不着，所以要恢复一下
    }

    public void unLock(){
        locked.set(false);
        LockSupport.unpark(waiters.peek());
    }
}
